util.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * util.c - Common utility functions
  3. *
  4. * Written 2009 by Werner Almesberger
  5. * Copyright 2009 by Werner Almesberger
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. */
  12. #include <stdarg.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include "util.h"
  16. /* ----- printf buffer allocation ------------------------------------------ */
  17. char *stralloc_vprintf(const char *fmt, va_list ap)
  18. {
  19. va_list aq;
  20. char *buf;
  21. int n;
  22. va_copy(aq, ap);
  23. n = vsnprintf(NULL, 0, fmt, aq);
  24. va_end(aq);
  25. buf = alloc_size(n+1);
  26. vsnprintf(buf, n+1, fmt, ap);
  27. return buf;
  28. }
  29. char *stralloc_printf(const char *fmt, ...)
  30. {
  31. va_list ap;
  32. char *s;
  33. va_start(ap, fmt);
  34. s = stralloc_vprintf(fmt, ap);
  35. va_end(ap);
  36. return s;
  37. }
  38. /* ----- identifier syntax check ------------------------------------------- */
  39. int is_id_char(char c, int first)
  40. {
  41. if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')
  42. return 1;
  43. if (first)
  44. return 0;
  45. return c >= '0' && c <= '9';
  46. }
  47. int is_id(const char *s)
  48. {
  49. const char *p;
  50. if (!*s)
  51. return 0;
  52. for (p = s; *p; p++)
  53. if (!is_id_char(*p, s == p))
  54. return 0;
  55. return 1;
  56. }
  57. /* ----- unique identifiers ------------------------------------------------ */
  58. static struct unique {
  59. char *s;
  60. struct unique *next;
  61. } *uniques = NULL;
  62. /* @@@ consider using rb trees */
  63. const char *unique(const char *s)
  64. {
  65. struct unique **walk;
  66. for (walk = &uniques; *walk; walk = &(*walk)->next)
  67. if (!strcmp(s, (*walk)->s))
  68. return (*walk)->s;
  69. *walk = alloc_type(struct unique);
  70. (*walk)->s = stralloc(s);
  71. (*walk)->next = NULL;
  72. return (*walk)->s;
  73. }
  74. void unique_cleanup(void)
  75. {
  76. struct unique *next;
  77. while (uniques) {
  78. next = uniques->next;
  79. free(uniques->s);
  80. free(uniques);
  81. uniques = next;
  82. }
  83. }