arg.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright (c) 2017 Richard Braun.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <assert.h>
  18. #include <stdbool.h>
  19. #include <stddef.h>
  20. #include <string.h>
  21. #include <kern/arg.h>
  22. #include <kern/init.h>
  23. #include <kern/log.h>
  24. #include <kern/macros.h>
  25. #include <kern/panic.h>
  26. /*
  27. * Internally, all space characters are turned into null bytes so that
  28. * values returned to callers directly point in the command line string,
  29. * with no need for dynamic allocation.
  30. */
  31. static char arg_cmdline[ARG_CMDLINE_MAX_SIZE] __initdata;
  32. static const char *arg_cmdline_end __initdata;
  33. void __init
  34. arg_set_cmdline (const char *cmdline)
  35. {
  36. strlcpy (arg_cmdline, cmdline, sizeof (arg_cmdline));
  37. }
  38. static int __init
  39. arg_setup (void)
  40. {
  41. size_t length = strlen (arg_cmdline);
  42. for (size_t i = 0; i < length; i++)
  43. if (arg_cmdline[i] == ' ')
  44. arg_cmdline[i] = '\0';
  45. arg_cmdline_end = arg_cmdline + length;
  46. return (0);
  47. }
  48. INIT_OP_DEFINE (arg_setup);
  49. void __init
  50. arg_log_info (void)
  51. {
  52. char cmdline[sizeof (arg_cmdline)];
  53. size_t i;
  54. for (i = 0; &arg_cmdline[i] < arg_cmdline_end; i++)
  55. cmdline[i] = arg_cmdline[i] ?: ' ';
  56. cmdline[i] = '\0';
  57. log_info ("arg: %s", cmdline);
  58. }
  59. static const char* __init
  60. arg_walk (const char *s)
  61. {
  62. if (s == NULL)
  63. s = arg_cmdline;
  64. else
  65. for ( ; ; ++s)
  66. if (s >= arg_cmdline_end)
  67. return (NULL);
  68. else if (*s == '\0')
  69. break;
  70. for ( ; ; ++s)
  71. {
  72. if (s >= arg_cmdline_end)
  73. return (NULL);
  74. else if (*s != '\0')
  75. return (s);
  76. }
  77. }
  78. static const char* __init
  79. arg_find_name_end (const char *arg)
  80. {
  81. const char *end = strchr (arg, '=');
  82. return (end ?: arg + strlen (arg));
  83. }
  84. static const char* __init
  85. arg_find (const char *name)
  86. {
  87. size_t name_length = strlen (name);
  88. assert (name_length);
  89. for (const char *arg = arg_walk (NULL); arg; arg = arg_walk (arg))
  90. {
  91. const char *arg_name_end = arg_find_name_end (arg);
  92. size_t arg_name_length = arg_name_end - arg;
  93. if (arg_name_length == name_length &&
  94. memcmp (arg, name, name_length) == 0)
  95. return (arg);
  96. }
  97. return (NULL);
  98. }
  99. bool __init
  100. arg_present (const char *name)
  101. {
  102. return (arg_find (name) != NULL);
  103. }
  104. const char* __init
  105. arg_value (const char *name)
  106. {
  107. const char *arg = arg_find (name);
  108. if (! arg)
  109. return (NULL);
  110. const char *value = strchr (arg, '=');
  111. return (value ? value + 1 : "");
  112. }