raylib_npp_parser.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /**********************************************************************************************
  2. raylib_npp_parser - raylib header parser to generate Notepad++ autocompletion data
  3. This parser scans raylib.h for functions that start with RLAPI and generates Notepad++
  4. autocompletion xml equivalent for function and parameters.
  5. Converts:
  6. RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
  7. To:
  8. <KeyWord name="Fade" func="yes">
  9. <Overload retVal="Color" descr="Color fade-in or fade-out, alpha goes from 0.0 to 1.0">
  10. <Param name="Color color" />
  11. <Param name="float alpha" />
  12. </Overload>
  13. </KeyWord>
  14. NOTE: Generated XML text should be copied inside raylib\Notepad++\plugins\APIs\c.xml
  15. WARNING: Be careful with functions that split parameters into several lines, it breaks the process!
  16. LICENSE: zlib/libpng
  17. raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  18. BSD-like license that allows static linking with closed source software:
  19. Copyright (c) 2018 Ramon Santamaria (@raysan5)
  20. **********************************************************************************************/
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <stdbool.h>
  24. #include <stdlib.h>
  25. #define MAX_BUFFER_SIZE 512
  26. int main(int argc, char *argv[])
  27. {
  28. if (argc > 1)
  29. {
  30. FILE *rFile = fopen(argv[1], "rt");
  31. FILE *rxmlFile = fopen("raylib_npp.xml", "wt");
  32. if ((rFile == NULL) || (rxmlFile == NULL))
  33. {
  34. printf("File could not be opened.\n");
  35. return 0;
  36. }
  37. char *buffer = (char *)calloc(MAX_BUFFER_SIZE, 1);
  38. int count = 0;
  39. while (!feof(rFile))
  40. {
  41. // Read one full line
  42. fgets(buffer, MAX_BUFFER_SIZE, rFile);
  43. if (buffer[0] == '/') fprintf(rxmlFile, " <!--%.*s -->\n", strlen(buffer) - 3, buffer + 2);
  44. else if (buffer[0] == '\n') fprintf(rxmlFile, "%s", buffer); // Direct copy of code comments
  45. else if (strncmp(buffer, "RLAPI", 5) == 0) // raylib function declaration
  46. {
  47. char funcType[64];
  48. char funcTypeAux[64];
  49. char funcName[64];
  50. char funcDesc[256];
  51. char params[128];
  52. char paramType[16][16];
  53. char paramName[16][32];
  54. int index = 0;
  55. char *ptr = NULL;
  56. sscanf(buffer, "RLAPI %s %[^(]s", funcType, funcName);
  57. if (strcmp(funcType, "const") == 0)
  58. {
  59. sscanf(buffer, "RLAPI %s %s %[^(]s", funcType, funcTypeAux, funcName);
  60. strcat(funcType, " ");
  61. strcat(funcType, funcTypeAux);
  62. }
  63. ptr = strchr(buffer, '/');
  64. index = (int)(ptr - buffer);
  65. sscanf(buffer + index, "%[^\n]s", funcDesc); // Read function comment after declaration
  66. ptr = strchr(buffer, '(');
  67. if (ptr != NULL) index = (int)(ptr - buffer);
  68. else printf("Character not found!\n");
  69. sscanf(buffer + (index + 1), "%[^)]s", params); // Read what's inside '(' and ')'
  70. // Scan params string for number of func params, type and name
  71. char *paramPtr[16]; // Allocate 16 pointers for possible parameters
  72. int paramsCount = 0;
  73. paramPtr[paramsCount] = strtok(params, ",");
  74. if ((funcName[0] == '*') && (funcName[1] == '*')) fprintf(rxmlFile, " <KeyWord name=\"%s\" func=\"yes\">\n", funcName + 2);
  75. else if (funcName[0] == '*') fprintf(rxmlFile, " <KeyWord name=\"%s\" func=\"yes\">\n", funcName + 1);
  76. else fprintf(rxmlFile, " <KeyWord name=\"%s\" func=\"yes\">\n", funcName);
  77. fprintf(rxmlFile, " <Overload retVal=\"%s\" descr=\"%s\">", funcType, funcDesc + 3);
  78. bool paramsVoid = false;
  79. char paramConst[8][16];
  80. while (paramPtr[paramsCount] != NULL)
  81. {
  82. sscanf(paramPtr[paramsCount], "%s %s\n", paramType[paramsCount], paramName[paramsCount]);
  83. if (strcmp(paramType[paramsCount], "void") == 0)
  84. {
  85. paramsVoid = true;
  86. break;
  87. }
  88. if ((strcmp(paramType[paramsCount], "const") == 0) || (strcmp(paramType[paramsCount], "unsigned") == 0))
  89. {
  90. sscanf(paramPtr[paramsCount], "%s %s %s\n", paramConst[paramsCount], paramType[paramsCount], paramName[paramsCount]);
  91. fprintf(rxmlFile, "\n <Param name=\"%s %s %s\" />", paramConst[paramsCount], paramType[paramsCount], paramName[paramsCount]);
  92. }
  93. else if (strcmp(paramType[paramsCount], "...") == 0) fprintf(rxmlFile, "\n <Param name=\"...\" />");
  94. else fprintf(rxmlFile, "\n <Param name=\"%s %s\" />", paramType[paramsCount], paramName[paramsCount]);
  95. paramsCount++;
  96. paramPtr[paramsCount] = strtok(NULL, ",");
  97. }
  98. fprintf(rxmlFile, "%s</Overload>\n", paramsVoid ? "" : "\n ");
  99. fprintf(rxmlFile, " </KeyWord>\n");
  100. count++;
  101. printf("Function processed %02i: %s\n", count, funcName);
  102. memset(buffer, 0, MAX_BUFFER_SIZE);
  103. }
  104. }
  105. free(buffer);
  106. fclose(rFile);
  107. fclose(rxmlFile);
  108. }
  109. return 0;
  110. }