Raymond Toy pushed to branch issue-365-add-strerror at cmucl / cmucl

Commits:

7 changed files:

Changes:

  • src/code/commandline.lisp
    ... ... @@ -109,7 +109,13 @@
    109 109
     	(return (setf *command-line-switches*
    
    110 110
     		      (nreverse *command-line-switches*))))
    
    111 111
           (let* ((position (position #\= (the simple-string str) :test #'char=))
    
    112
    -	     (switch (subseq (the simple-string str) 1 position))
    
    112
    +	     ;; Extract the name of the switch.  The actual arg can be
    
    113
    +	     ;; "-switch" or "--switch".
    
    114
    +	     (switch (subseq (the simple-string str)
    
    115
    +			     (position-if-not #'(lambda (c)
    
    116
    +						  (char= c #\-))
    
    117
    +					      str)
    
    118
    +			     position))
    
    113 119
     	     (value (if position
    
    114 120
     			(subseq (the simple-string str) (1+ position)
    
    115 121
     				(length (the simple-string str))))))
    
    ... ... @@ -143,7 +149,14 @@
    143 149
       the switch.  If no value was specified, then any following words are
    
    144 150
       returned.  If there are no following words, then t is returned.  If
    
    145 151
       the switch was not specified, then nil is returned."
    
    146
    -  (let* ((name (if (char= (schar sname 0) #\-) (subseq sname 1) sname))
    
    152
    +  (let* ((posn (position-if-not #'(lambda (ch)
    
    153
    +				    (char= ch #\-))
    
    154
    +				sname))
    
    155
    +	 ;; Strip up to 2 leading "-" to get the switch name.
    
    156
    +	 ;; Otherwise, return the entire switch name.
    
    157
    +	 (name (if (and posn (<= posn 2))
    
    158
    +		   (subseq sname posn)
    
    159
    +		   sname))
    
    147 160
     	 (switch (find name *command-line-switches*
    
    148 161
     		       :test #'string-equal
    
    149 162
     		       :key #'cmd-switch-name)))
    
    ... ... @@ -177,17 +190,17 @@
    177 190
     					 (demons *command-switch-demons*))
    
    178 191
       (flet ((invoke-demon (switch)
    
    179 192
     	   (let* ((name (cmd-switch-name switch))
    
    180
    -		  (demon (cdr (assoc name demons :test #'string-equal))))
    
    193
    +		  (demon (cdr (assoc name demons :test #'string=))))
    
    181 194
     	     (cond (demon (funcall demon switch))
    
    182
    -		   ((or (member name *legal-cmd-line-switches* :test #'string-equal :key #'car)
    
    195
    +		   ((or (member name *legal-cmd-line-switches* :test #'string= :key #'car)
    
    183 196
     			(not *complain-about-illegal-switches*)))
    
    184 197
     		   (t (warn (intl:gettext "~S is an illegal switch") switch)))
    
    185 198
     	     (lisp::finish-standard-output-streams))))
    
    186 199
         ;; We want to process -help (or --help) first, if it's given.
    
    187 200
         ;; Since we're asking for help, we don't want to process any of
    
    188 201
         ;; the other switches.
    
    189
    -    (let ((maybe-help (or (find "help" switches :key #'cmd-switch-name :test #'string-equal)
    
    190
    -			  (find "-help" switches :key #'cmd-switch-name :test #'string-equal))))
    
    202
    +    (let ((maybe-help (or (find "help" switches :key #'cmd-switch-name :test #'string=)
    
    203
    +			  (find "-help" switches :key #'cmd-switch-name :test #'string=))))
    
    191 204
           (if maybe-help
    
    192 205
     	(invoke-demon maybe-help)
    
    193 206
     	(dolist (switch switches t)
    
    ... ... @@ -230,12 +243,12 @@
    230 243
     	(lisp::finish-standard-output-streams)
    
    231 244
     	(setf start next)))))
    
    232 245
     
    
    233
    -;; Docstrings should have lines longer than 72 characters so that we
    
    234
    -;; can print out the docstrings nicely on one line for help.
    
    235
    -;;                                                                     | <-- char 72
    
    246
    +;; Docstrings MUST consist of simple text and punctuation and
    
    247
    +;; newlines; no special markup is allowed.  When help is printed, the
    
    248
    +;; help string is automatically filled and wrapped to 80 columns.
    
    236 249
     (defswitch "eval" #'eval-switch-demon
    
    237 250
       "Evaluate the specified Lisp expression during the start up
    
    238
    -  sequence.  the value of the form will not be printed unless it is
    
    251
    +  sequence.  The value of the form will not be printed unless it is
    
    239 252
       wrapped in a form that does output."
    
    240 253
       "expression")
    
    241 254
     
    
    ... ... @@ -325,7 +338,7 @@
    325 338
     
    
    326 339
     (defswitch "quiet" nil
    
    327 340
       "Causes Lisp to start up silently, disabling printing of the herald
    
    328
    -  and causing most unnecessary noise, like GC messages,load messages,
    
    341
    +  and causing most unnecessary noise, like GC messages, load messages,
    
    329 342
       etc. to be suppressed.")
    
    330 343
     
    
    331 344
     (defswitch "debug-lisp-search" nil
    
    ... ... @@ -338,7 +351,8 @@
    338 351
     
    
    339 352
     (defun help-switch-demon (switch)
    
    340 353
       (declare (ignore switch))
    
    341
    -  (format t (intl:gettext "~&Usage: ~A <options>~2%") *command-line-utility-name*)
    
    354
    +  (format t (intl:gettext "~&Usage: ~A <options> [-- [app-args]*]~2%")
    
    355
    +	  *command-line-utility-name*)
    
    342 356
       (flet
    
    343 357
           ((get-words (s)
    
    344 358
     	 (declare (string s))
    
    ... ... @@ -366,7 +380,12 @@
    366 380
     		     :key #'car))
    
    367 381
           (destructuring-bind (name doc arg)
    
    368 382
     	  s
    
    369
    -	(format t "    -~A ~@[~A~]~%" name (if arg (intl:gettext arg)))
    
    383
    +	;; Print both -switch and --switch, and the optional arg
    
    384
    +	;; value.
    
    385
    +	(format t "    -~A|--~A   ~@[~A~]~%"
    
    386
    +		name name
    
    387
    +		(if arg (intl:gettext arg)))
    
    388
    +
    
    370 389
     	;; Poor man's formatting of the help string
    
    371 390
     	(let ((*print-right-margin* 80))
    
    372 391
     	  ;; Extract all the words from the string and print them out
    
    ... ... @@ -392,9 +411,6 @@
    392 411
     (defswitch "help" #'help-switch-demon
    
    393 412
       "Print out the command line options and exit")
    
    394 413
     
    
    395
    -(defswitch "-help" #'help-switch-demon
    
    396
    -  "Same as -help.")
    
    397
    -
    
    398 414
     (defun version-switch-demon (switch)
    
    399 415
       (declare (ignore switch))
    
    400 416
       (format t "~A~%" (lisp-implementation-version))
    
    ... ... @@ -406,8 +422,3 @@
    406 422
     ;; it out so the user knows about it.
    
    407 423
     (defswitch "version" #'version-switch-demon
    
    408 424
       "Prints the cmucl version and exits, without loading the lisp core.")
    409
    -
    
    410
    -;; Make --version work for the benefit of those who are accustomed to
    
    411
    -;; GNU software.
    
    412
    -(defswitch "-version" #'version-switch-demon
    
    413
    -  "Prints the cmucl version and exits; same as -version")

  • src/code/unix.lisp
    ... ... @@ -2600,31 +2600,74 @@
    2600 2600
     (defun unix-mkstemp (template)
    
    2601 2601
       _N"Generates a unique temporary file name from TEMPLATE, and creates
    
    2602 2602
       and opens the file.  On success, the corresponding file descriptor
    
    2603
    -  and name of the file is returned.
    
    2604
    -
    
    2605
    - The last six characters of the template must be \"XXXXXX\"."
    
    2606
    -  ;; Hope this buffer is large enough!
    
    2607
    -  (let ((octets (%name->file template)))
    
    2608
    -    (syscall ("mkstemp" c-call:c-string)
    
    2603
    +  and name of the file is returned.  Otherwise, NIL and the UNIX error
    
    2604
    +  code is returned."
    
    2605
    +  (let* ((format (if (eql *filename-encoding* :null)
    
    2606
    +		     :iso8859-1
    
    2607
    +		     *filename-encoding*))
    
    2608
    +	 ;; Convert the string to octets using the
    
    2609
    +	 ;; *FILENAME-ENCODING*.  Should we signal an error if the
    
    2610
    +	 ;; string can't be encoded?
    
    2611
    +	 (octets (stream:string-to-octets template
    
    2612
    +					  :external-format format))
    
    2613
    +	 (length (length octets)))
    
    2614
    +    (with-alien ((buffer (* c-call:unsigned-char)))
    
    2615
    +      (setf buffer (make-alien c-call:unsigned-char (1+ length)))
    
    2616
    +      ;; Copy the octets from OCTETS to the null-terminated array BUFFER.
    
    2617
    +      (system:without-gcing
    
    2618
    +	  (kernel:system-area-copy (vector-sap octets) 0
    
    2619
    +				   (alien-sap buffer) 0
    
    2620
    +				   (* length vm:byte-bits)))
    
    2621
    +      (setf (deref buffer length) 0)
    
    2622
    +
    
    2623
    +      (syscall ("mkstemp" (* c-call:char))
    
    2609 2624
     	       (values result
    
    2610
    -		       ;; Convert the file name back to a Lisp string.
    
    2611
    -		       (%file->name octets))
    
    2612
    -	       octets)))
    
    2625
    +		       (progn
    
    2626
    +			 ;; Copy out the alien bytes and convert back
    
    2627
    +			 ;; to a lisp string.
    
    2628
    +			 (system:without-gcing
    
    2629
    +			     (kernel:system-area-copy (alien-sap buffer) 0
    
    2630
    +						      (vector-sap octets) 0
    
    2631
    +						      (* length vm:byte-bits)))
    
    2632
    +			 (stream:octets-to-string octets
    
    2633
    +						  :external-format format)))
    
    2634
    +	       (cast buffer (* c-call:char))))))
    
    2613 2635
     
    
    2614 2636
     (defun unix-mkdtemp (template)
    
    2615
    -  _N"Generate a uniquely named temporary directory from Template,
    
    2616
    -  which must have \"XXXXXX\" as the last six characters.  The
    
    2637
    +  _N"Generate a uniquely named temporary directory from Template.  The
    
    2617 2638
       directory is created with permissions 0700.  The name of the
    
    2618
    -  directory is returned."
    
    2619
    -  (let* ((octets (%name->file template))
    
    2620
    -	 (result (alien-funcall
    
    2621
    -		  (extern-alien "mkdtemp"
    
    2622
    -				(function (* char)
    
    2623
    -					  c-call:c-string))
    
    2624
    -		  octets)))
    
    2625
    -    (if (null-alien result)
    
    2626
    -	(values nil (unix-errno))
    
    2627
    -	(%file->name octets))))
    
    2639
    +  directory is returned.
    
    2640
    +
    
    2641
    +  If the directory cannot be created NIL and the UNIX error code is
    
    2642
    +  returned."
    
    2643
    +  (let* ((format (if (eql *filename-encoding* :null)
    
    2644
    +		     :iso8859-1
    
    2645
    +		     *filename-encoding*))
    
    2646
    +	 ;; Encode the string using the appropriate
    
    2647
    +	 ;; *filename-encoding*.  Should we signal an error if the
    
    2648
    +	 ;; string can't be encoded in that format?
    
    2649
    +	 (octets (stream:string-to-octets template
    
    2650
    +					  :external-format format))
    
    2651
    +	 (length (length octets)))
    
    2652
    +    (with-alien ((buffer (* c-call:unsigned-char)))
    
    2653
    +      (setf buffer (make-alien c-call:unsigned-char (1+ length)))
    
    2654
    +      ;; Copy the octets from OCTETS to the null-terminated array BUFFER.
    
    2655
    +      (system:without-gcing
    
    2656
    +	  (kernel:system-area-copy (vector-sap octets) 0
    
    2657
    +				   (alien-sap buffer) 0
    
    2658
    +				   (* length vm:byte-bits)))
    
    2659
    +      (setf (deref buffer length) 0)
    
    2660
    +
    
    2661
    +      (let ((result (alien-funcall
    
    2662
    +		     (extern-alien "mkdtemp"
    
    2663
    +				   (function (* char)
    
    2664
    +					     (* char)))
    
    2665
    +		     (cast buffer (* char)))))
    
    2666
    +	;; If mkdtemp worked, a non-NIL value is returned, return the
    
    2667
    +	;; resulting name.  Otherwise, return NIL and the errno.
    
    2668
    +	(if (null-alien result)
    
    2669
    +	    (values nil (unix-errno))
    
    2670
    +	    (%file->name (cast result c-call:c-string)))))))
    
    2628 2671
     
    
    2629 2672
     (defun unix-strerror (errno)
    
    2630 2673
       _N"Returns a string that describes the error code Errno"
    

  • src/general-info/release-21f.md
    ... ... @@ -119,6 +119,7 @@ public domain.
    119 119
         * ~~#364~~ Add interface to `mkdtemp` and `mkstemp`
    
    120 120
         * ~~#367~~ Add stream:string-count-octets to count octets in a string
    
    121 121
         * ~~#369~~ Improve docstring for `unix::unix-setlocale`
    
    122
    +    * ~~#379~~ Support GNU-style command-line option names
    
    122 123
       * Other changes:
    
    123 124
       * Improvements to the PCL implementation of CLOS:
    
    124 125
       * Changes to building procedure:
    

  • src/i18n/locale/cmucl-unix.pot
    ... ... @@ -1342,17 +1342,18 @@ msgstr ""
    1342 1342
     msgid ""
    
    1343 1343
     "Generates a unique temporary file name from TEMPLATE, and creates\n"
    
    1344 1344
     "  and opens the file.  On success, the corresponding file descriptor\n"
    
    1345
    -"  and name of the file is returned.\n"
    
    1346
    -"\n"
    
    1347
    -" The last six characters of the template must be \"XXXXXX\"."
    
    1345
    +"  and name of the file is returned.  Otherwise, NIL and the UNIX error\n"
    
    1346
    +"  code is returned."
    
    1348 1347
     msgstr ""
    
    1349 1348
     
    
    1350 1349
     #: src/code/unix.lisp
    
    1351 1350
     msgid ""
    
    1352
    -"Generate a uniquely named temporary directory from Template,\n"
    
    1353
    -"  which must have \"XXXXXX\" as the last six characters.  The\n"
    
    1351
    +"Generate a uniquely named temporary directory from Template.  The\n"
    
    1354 1352
     "  directory is created with permissions 0700.  The name of the\n"
    
    1355
    -"  directory is returned."
    
    1353
    +"  directory is returned.\n"
    
    1354
    +"\n"
    
    1355
    +"  If the directory cannot be created NIL and the UNIX error code is\n"
    
    1356
    +"  returned."
    
    1356 1357
     msgstr ""
    
    1357 1358
     
    
    1358 1359
     #: src/code/unix.lisp
    

  • src/i18n/locale/cmucl.pot
    ... ... @@ -6060,7 +6060,7 @@ msgstr ""
    6060 6060
     #: src/code/commandline.lisp
    
    6061 6061
     msgid ""
    
    6062 6062
     "Evaluate the specified Lisp expression during the start up\n"
    
    6063
    -"  sequence.  the value of the form will not be printed unless it is\n"
    
    6063
    +"  sequence.  The value of the form will not be printed unless it is\n"
    
    6064 6064
     "  wrapped in a form that does output."
    
    6065 6065
     msgstr ""
    
    6066 6066
     
    
    ... ... @@ -6182,7 +6182,7 @@ msgstr ""
    6182 6182
     #: src/code/commandline.lisp
    
    6183 6183
     msgid ""
    
    6184 6184
     "Causes Lisp to start up silently, disabling printing of the herald\n"
    
    6185
    -"  and causing most unnecessary noise, like GC messages,load messages,\n"
    
    6185
    +"  and causing most unnecessary noise, like GC messages, load messages,\n"
    
    6186 6186
     "  etc. to be suppressed."
    
    6187 6187
     msgstr ""
    
    6188 6188
     
    
    ... ... @@ -6197,25 +6197,17 @@ msgid "Specify the unidata.bin file to be used."
    6197 6197
     msgstr ""
    
    6198 6198
     
    
    6199 6199
     #: src/code/commandline.lisp
    
    6200
    -msgid "~&Usage: ~A <options>~2%"
    
    6200
    +msgid "~&Usage: ~A <options> [-- [app-args]*]~2%"
    
    6201 6201
     msgstr ""
    
    6202 6202
     
    
    6203 6203
     #: src/code/commandline.lisp
    
    6204 6204
     msgid "Print out the command line options and exit"
    
    6205 6205
     msgstr ""
    
    6206 6206
     
    
    6207
    -#: src/code/commandline.lisp
    
    6208
    -msgid "Same as -help."
    
    6209
    -msgstr ""
    
    6210
    -
    
    6211 6207
     #: src/code/commandline.lisp
    
    6212 6208
     msgid "Prints the cmucl version and exits, without loading the lisp core."
    
    6213 6209
     msgstr ""
    
    6214 6210
     
    
    6215
    -#: src/code/commandline.lisp
    
    6216
    -msgid "Prints the cmucl version and exits; same as -version"
    
    6217
    -msgstr ""
    
    6218
    -
    
    6219 6211
     #: src/code/env-access.lisp
    
    6220 6212
     msgid ""
    
    6221 6213
     "Returns information about the symbol VAR in the lexical environment ENV.\n"
    

  • src/lisp/lisp.c
    ... ... @@ -460,6 +460,41 @@ core_failure(const char* core, const char* argv[])
    460 460
         exit(1);
    
    461 461
     }
    
    462 462
     
    
    463
    +/*
    
    464
    + * Match the actual command line option "arg" with the arg name in
    
    465
    + * "argname".  The option matches if it is exacty the arg name
    
    466
    + * prefixed by either one or two "-" characters.
    
    467
    + *
    
    468
    + * Returns non-zero if it matches.
    
    469
    + */
    
    470
    +int match_option(const char* arg, const char* argname)
    
    471
    +{
    
    472
    +    if ((strlen(arg) < 2) || strlen(argname) < 1) {
    
    473
    +	/*
    
    474
    +	 * The actual arg must be at least 2 characters.  The argname
    
    475
    +	 * must have at least 1.
    
    476
    +	 */
    
    477
    +	return 0;
    
    478
    +    }
    
    479
    +
    
    480
    +    /* Must start with a "-" */
    
    481
    +    if (arg[0] != '-') {
    
    482
    +	return 0;
    
    483
    +    }
    
    484
    +
    
    485
    +    if (strcmp(arg + 1, argname) == 0) {
    
    486
    +	/* We have "-" followed by the argname.  That's a match. */
    
    487
    +	return 1;
    
    488
    +    }
    
    489
    +    
    
    490
    +    if ((arg[1] == '-') && (strcmp(arg + 2, argname) == 0)) {
    
    491
    +	/* We have "--" followed by the argname.  That's a match. */
    
    492
    +	return 1;
    
    493
    +    }
    
    494
    +
    
    495
    +    return 0;
    
    496
    +}
    
    497
    +    
    
    463 498
     int
    
    464 499
     main(int argc, const char *argv[], const char *envp[])
    
    465 500
     {
    
    ... ... @@ -529,7 +564,7 @@ main(int argc, const char *argv[], const char *envp[])
    529 564
     
    
    530 565
         argptr = argv;
    
    531 566
         while ((arg = *++argptr) != NULL) {
    
    532
    -	if (strcmp(arg, "-core") == 0) {
    
    567
    +	if (match_option(arg, "core")) {
    
    533 568
     	    if (builtin_image_flag) {
    
    534 569
     		fprintf(stderr,
    
    535 570
     			"Warning:  specifying a core file with an executable image is unusual,\nbut should work.\n");
    
    ... ... @@ -543,87 +578,98 @@ main(int argc, const char *argv[], const char *envp[])
    543 578
     	    core = *++argptr;
    
    544 579
     	    if (core == NULL) {
    
    545 580
     		fprintf(stderr,
    
    546
    -			"-core must be followed by the name of the core file to use.\n");
    
    581
    +			"%s must be followed by the name of the core file to use.\n",
    
    582
    +			arg);
    
    547 583
     		exit(1);
    
    548 584
     	    }
    
    549
    -	} else if (strcmp(arg, "-lib") == 0) {
    
    585
    +	} else if (match_option(arg, "lib")) {
    
    550 586
     	    lib = *++argptr;
    
    551 587
     	    if (lib == NULL) {
    
    552 588
     		fprintf(stderr,
    
    553
    -			"-lib must be followed by a string denoting the CMUCL library path.\n");
    
    589
    +			"%s must be followed by a string denoting the CMUCL library path.\n",
    
    590
    +			arg);
    
    554 591
     		exit(1);
    
    555 592
     	    }
    
    556
    -        } else if (strcmp(arg, "-read-only-space-size") == 0) {
    
    593
    +        } else if (match_option(arg, "read-only-space-size")) {
    
    557 594
                 const char *str = *++argptr;
    
    558 595
     
    
    559 596
                 if (str == NULL) {
    
    560 597
                     fprintf(stderr,
    
    561
    -                        "-read-only-space-size must be followed by the size in MBytes.\n");
    
    598
    +                        "%s must be followed by the size in MBytes.\n",
    
    599
    +			arg);
    
    562 600
                     exit(1);
    
    563 601
                 }
    
    564 602
                 read_only_space_size = atoi(str) * 1024 * 1024;
    
    565 603
                 if (read_only_space_size > READ_ONLY_SPACE_SIZE) {
    
    566 604
                     fprintf(stderr,
    
    567
    -                        "-read-only-space-size must be no greater than %lu MBytes.\n",
    
    605
    +                        "%s must be no greater than %lu MBytes.\n",
    
    606
    +			arg,
    
    568 607
                             READ_ONLY_SPACE_SIZE / (1024 * 1024UL));
    
    569 608
                     fprintf(stderr, "  Continuing with default size.\n");
    
    570 609
                     read_only_space_size = READ_ONLY_SPACE_SIZE;
    
    571 610
                 }
    
    572
    -        } else if (strcmp(arg, "-static-space-size") == 0) {
    
    611
    +        } else if (match_option(arg, "static-space-size")) {
    
    573 612
                 const char *str = *++argptr;
    
    574 613
     
    
    575 614
                 if (str == NULL) {
    
    576 615
                     fprintf(stderr,
    
    577
    -                        "-static-space-size must be followed by the size in MBytes.\n");
    
    616
    +                        "%s must be followed by the size in MBytes.\n",
    
    617
    +			arg);
    
    578 618
                     exit(1);
    
    579 619
                 }
    
    580 620
                 static_space_size = atoi(str) * 1024 * 1024;
    
    581 621
                 if (static_space_size > STATIC_SPACE_SIZE) {
    
    582 622
                     fprintf(stderr,
    
    583
    -                        "-static-space-size must be no greater than %lu MBytes.\n",
    
    623
    +                        "%s must be no greater than %lu MBytes.\n",
    
    624
    +			arg,
    
    584 625
                             STATIC_SPACE_SIZE / (1024 * 1024UL));
    
    585 626
                     fprintf(stderr, "  Continuing with default size.\n");
    
    586 627
                     static_space_size = STATIC_SPACE_SIZE;
    
    587 628
                 }
    
    588
    -        } else if (strcmp(arg, "-binding-stack-size") == 0) {
    
    629
    +        } else if (match_option(arg, "binding-stack-size")) {
    
    589 630
                 const char *str = *++argptr;
    
    590 631
     
    
    591 632
                 if (str == NULL) {
    
    592 633
                     fprintf(stderr,
    
    593
    -                        "-binding-stack-size must be followed by the size in MBytes.\n");
    
    634
    +                        "%s must be followed by the size in MBytes.\n",
    
    635
    +			arg);
    
    594 636
                     exit(1);
    
    595 637
                 }
    
    596 638
                 binding_stack_size = atoi(str) * 1024 * 1024;
    
    597 639
                 if (binding_stack_size > BINDING_STACK_SIZE) {
    
    598 640
                     fprintf(stderr,
    
    599
    -                        "-binding-stack-size must be no greater than %lu MBytes.\n",
    
    641
    +                        "%s must be no greater than %lu MBytes.\n",
    
    642
    +			arg,
    
    600 643
                             BINDING_STACK_SIZE / (1024 * 1024UL));
    
    601 644
                     fprintf(stderr, "  Continuing with default size.\n");
    
    602 645
                     binding_stack_size = BINDING_STACK_SIZE;
    
    603 646
                 }
    
    604
    -        } else if (strcmp(arg, "-control-stack-size") == 0) {
    
    647
    +        } else if (match_option(arg, "control-stack-size")) {
    
    605 648
                 const char *str = *++argptr;
    
    606 649
     
    
    607 650
                 if (str == NULL) {
    
    608 651
                     fprintf(stderr,
    
    609
    -                        "-control-stack-size must be followed by the size in MBytes.\n");
    
    652
    +                        "%s must be followed by the size in MBytes.\n",
    
    653
    +			arg);
    
    610 654
                     exit(1);
    
    611 655
                 }
    
    612 656
                 control_stack_size = atoi(str) * 1024 * 1024;
    
    613 657
                 if (control_stack_size > CONTROL_STACK_SIZE) {
    
    614 658
                     fprintf(stderr,
    
    615
    -                        "-control-stack-size must be no greater than %lu MBytes.\n",
    
    659
    +                        "%s must be no greater than %lu MBytes.\n",
    
    660
    +			arg,
    
    616 661
                             CONTROL_STACK_SIZE / (1024 * 1024UL));
    
    617 662
                     fprintf(stderr, "  Continuing with default size.\n");
    
    618 663
                     control_stack_size = CONTROL_STACK_SIZE;
    
    619 664
                 }
    
    620
    -	} else if (strcmp(arg, "-dynamic-space-size") == 0) {
    
    665
    +	} else if (match_option(arg, "dynamic-space-size")) {
    
    621 666
     	    const char *str;
    
    622 667
     
    
    623 668
     	    str = *++argptr;
    
    624 669
     	    if (str == NULL) {
    
    625 670
     		fprintf(stderr,
    
    626
    -			"-dynamic-space-size must be followed by the size to use in MBytes.\n");
    
    671
    +			"%s must be followed by the size to use in MBytes.\n",
    
    672
    +			arg);
    
    627 673
     		exit(1);
    
    628 674
     	    }
    
    629 675
     #ifndef sparc
    
    ... ... @@ -669,15 +715,16 @@ main(int argc, const char *argv[], const char *envp[])
    669 715
     #endif
    
    670 716
     	    if (dynamic_space_size > DYNAMIC_SPACE_SIZE) {
    
    671 717
     		fprintf(stderr,
    
    672
    -			"-dynamic-space-size must be no greater than %lu MBytes.\n",
    
    718
    +			"%s must be no greater than %lu MBytes.\n",
    
    719
    +			arg,
    
    673 720
     			DYNAMIC_SPACE_SIZE / (1024 * 1024UL));
    
    674 721
     		exit(1);
    
    675 722
     	    }
    
    676
    -	} else if (strcmp(arg, "-monitor") == 0) {
    
    723
    +	} else if (match_option(arg, "monitor")) {
    
    677 724
     	    monitor = TRUE;
    
    678
    -	} else if (strcmp(arg, "-debug-lisp-search") == 0) {
    
    725
    +	} else if (match_option(arg, "debug-lisp-search")) {
    
    679 726
     	    debug_lisp_search = TRUE;
    
    680
    -        } else if (strcmp(arg, "-unidata") == 0) {
    
    727
    +        } else if (match_option(arg, "unidata")) {
    
    681 728
               unidata = *++argptr;
    
    682 729
             } else if ((strcmp(arg, "-version") == 0) ||
    
    683 730
     		   (strcmp(arg, "--version") == 0)) {
    
    ... ... @@ -904,7 +951,7 @@ main(int argc, const char *argv[], const char *envp[])
    904 951
     
    
    905 952
         argptr = argv;
    
    906 953
         while ((arg = *++argptr) != NULL) {
    
    907
    -	if (strcmp(arg, "-batch") == 0)
    
    954
    +	if (match_option(arg, "batch"))
    
    908 955
     	    SetSymbolValue(BATCH_MODE, T);
    
    909 956
         }
    
    910 957
     
    

  • tests/unix.lisp
    1
    +;;; Tests for the unix interface
    
    2
    +
    
    3
    +(defpackage :unix-tests
    
    4
    +  (:use :cl :lisp-unit))
    
    5
    +
    
    6
    +(in-package "UNIX-TESTS")
    
    7
    +
    
    8
    +(define-test mkstemp.name-returned
    
    9
    +  (:tag :issues)
    
    10
    +  (let (fd filename)
    
    11
    +    (unwind-protect
    
    12
    +	 (progn
    
    13
    +	   (let ((template "test-XXXXXX"))
    
    14
    +	     (multiple-value-setq (fd filename)
    
    15
    +	       (unix::unix-mkstemp (copy-seq template)))
    
    16
    +	     (assert-true fd)
    
    17
    +	     (assert-true (equalp (length filename) (length template)))
    
    18
    +	     (assert-false (equalp filename template))
    
    19
    +	     (assert-true (>= 5 (mismatch filename template))))))
    
    20
    +      (when fd
    
    21
    +	(unix:unix-unlink filename)))))
    
    22
    +
    
    23
    +(define-test mkstemp.non-ascii-name-returned
    
    24
    +  (:tag :issues)
    
    25
    +  (let ((unix::*filename-encoding* :utf-8)
    
    26
    +	fd name)
    
    27
    +    (unwind-protect
    
    28
    +	 (progn
    
    29
    +	   ;; Temp name starts with a lower case alpha character.
    
    30
    +	   (let* ((template (concatenate 'string (string #\u+3b1)
    
    31
    +					 "test-XXXXXX"))
    
    32
    +		  (x-posn (position #\X template)))
    
    33
    +	     (multiple-value-setq (fd name)
    
    34
    +	       (unix::unix-mkstemp template))
    
    35
    +	     (assert-true fd)
    
    36
    +	     (assert-false (search "XXXXXX" name)
    
    37
    +			   name)
    
    38
    +	     (assert-true (string= name template :end1 x-posn :end2 x-posn)
    
    39
    +			  name)))
    
    40
    +      (when fd
    
    41
    +	(unix:unix-unlink name)))))
    
    42
    +
    
    43
    +(define-test mkstemp.bad-path
    
    44
    +  (:tag :issues)
    
    45
    +  (multiple-value-bind (fd errno)
    
    46
    +      ;; Assumes that the directory "random-dir" doesn't exist
    
    47
    +      (unix::unix-mkstemp "random-dir/test-XXXXXX")
    
    48
    +    ;; Can't create and open the file so the FD should be NIL, and a
    
    49
    +    ;; positive Unix errno value should be returned.
    
    50
    +    (assert-false fd)
    
    51
    +    (assert-true (and (integerp errno) (plusp errno)))))
    
    52
    +
    
    53
    +(define-test mkdtemp.name-returned
    
    54
    +  (:tag :issues)
    
    55
    +  (let (name)
    
    56
    +    (unwind-protect
    
    57
    +	 (progn
    
    58
    +	   (setf name (unix::unix-mkdtemp "dir-XXXXXX"))
    
    59
    +	   ;; Verify that the dir name no longer has X's.
    
    60
    +	   (assert-true (stringp name))
    
    61
    +	   (assert-false (search "XXXXXX" name)))
    
    62
    +      (when name
    
    63
    +	(unix:unix-rmdir name)))))
    
    64
    +
    
    65
    +(define-test mkdtemp.non-ascii-name-returned
    
    66
    +  (:tag :issues)
    
    67
    +  (let ((unix::*filename-encoding* :utf-8)
    
    68
    +	name)
    
    69
    +    (unwind-protect
    
    70
    +	 (progn
    
    71
    +	   ;; Temp name starts with a lower case alpha character.
    
    72
    +	   (let* ((template (concatenate 'string (string #\u+3b1)
    
    73
    +					 "dir-XXXXXX"))
    
    74
    +		  (x-posn (position #\X template)))
    
    75
    +	     (setf name (unix::unix-mkdtemp template))
    
    76
    +	     ;; Verify that the dir name no longer has X's.
    
    77
    +	     (assert-true (stringp name))
    
    78
    +	     (assert-false (search "XXXXXX" name))
    
    79
    +	     (assert-true (string= name template :end1 x-posn :end2 x-posn)
    
    80
    +			  name x-posn)))
    
    81
    +      (when name
    
    82
    +	(unix:unix-rmdir name)))))
    
    83
    +
    
    84
    +(define-test mkdtemp.bad-path
    
    85
    +  (:tag :issues)
    
    86
    +  (multiple-value-bind (result errno)
    
    87
    +      (unix::unix-mkdtemp "random-dir/dir-XXXXXX")
    
    88
    +    (assert-false result)
    
    89
    +    (assert-true (and (integerp errno) (plusp errno)))))
    
    90
    +
    
    91
    +