825908d2934375d6b1608653322fa095fe9560a8
2 * Generate a file with test registrations from a list
3 * of files in a directory.
4 * Casper S. Hornstrup <chorns@users.sourceforge.net>
19 #include <sys/types.h>
28 #define DIR_SEPARATOR_CHAR '/'
29 #define DIR_SEPARATOR_STRING "/"
31 #define DIR_SEPARATOR_CHAR '\\'
32 #define DIR_SEPARATOR_STRING "\\"
38 static char *makefile
;
39 static char *umstubfile
;
40 static char *kmstubfile
;
42 char* convert_path(char* origpath
)
47 /* for no good reason, i'm having trouble getting gcc to link strdup */
48 //newpath = strdup(origpath);
49 newpath
= malloc(strlen(origpath
)+1);
50 strcpy(newpath
, origpath
);
53 while (newpath
[i
] != 0)
56 if (newpath
[i
] == '\\')
62 if (newpath
[i
] == '/')
73 static void write_line(char *line
)
78 memset(buf
, 0, sizeof(buf
));
80 /* Terminate the line */
81 buf
[strlen(buf
)] = '\r';
82 buf
[strlen(buf
)] = '\n';
84 n_out
= fwrite(&buf
[0], 1, strlen(buf
), out
);
87 static void change_extension(char *filenamebuffer
, char *filename
, char *newextension
)
91 if (newextension
== NULL
)
93 strcpy(filenamebuffer
, filename
);
97 ptr
= strrchr(filename
, '.');
100 strncpy(filenamebuffer
, filename
, ptr
- filename
);
101 filenamebuffer
[ptr
- filename
] = 0;
102 strcat(filenamebuffer
, newextension
);
106 strcpy(filenamebuffer
, filename
);
107 strcat(filenamebuffer
, newextension
);
112 * filename - name of file to make registrations for
113 * regtype - type of registration (0 = prototype, 1 = call, 2 = makefile)
115 void register_test(char *filename
, int type
)
121 char filenamebuffer
[MAX_PATH
];
124 strcpy(testname
, filename
);
126 i
= strlen(testname
);
127 while (i
> 0 && testname
[i
] != '.')
133 memset(ext
, 0, sizeof(ext
));
134 strncpy(&ext
[0], &testname
[i
], strlen(&testname
[i
]));
136 if ((strncmp(ext
, ".c", 2) != 0) && (strncmp(ext
, ".C", 2) != 0))
148 // Make a capital first letter and make all other letters lower case
149 testname
[0] = toupper(testname
[0]);
150 if (!((testname
[0] >= 'A' && testname
[0] <= 'Z') ||
151 (testname
[0] >= '0' && testname
[0] <= '9')))
156 while (j
< strlen(testname
))
158 testname
[j
] = tolower(testname
[j
]);
159 if (!((testname
[j
] >= 'a' && testname
[j
] <= 'z') ||
160 (testname
[j
] >= '0' && testname
[j
] <= '9')))
169 sprintf(regtest
, "extern int %sTest(int Command, char *Buffer);", testname
);
174 sprintf(call
, "%sTest", testname
);
175 sprintf(regtest
, " AddTest((TestRoutine)%s);", call
);
180 change_extension(filenamebuffer
, filename
, ".o");
181 sprintf(regtest
, "%s \\", filenamebuffer
);
191 make_file_list (int type
)
193 struct _finddata_t f
;
195 char searchbuf
[MAX_PATH
];
197 strcpy(searchbuf
, path
);
198 strcat(searchbuf
, "*.*");
199 findhandle
=_findfirst(searchbuf
, &f
);
200 if (findhandle
!= -1)
204 if (f
.attrib
& _A_SUBDIR
)
206 /* Skip subdirectories */
210 register_test(f
.name
, type
);
212 while (_findnext(findhandle
, &f
) == 0);
213 _findclose(findhandle
);
221 make_file_list (int type
)
224 struct dirent
*entry
;
229 dirp
= opendir(path
);
232 while ((entry
= readdir(dirp
)) != NULL
)
234 if (strcmp(entry
->d_name
, ".") == 0 || strcmp(entry
->d_name
, "..") == 0)
235 continue; // skip self and parent
237 if (entry
->d_type
== DT_REG
) // normal file
239 // Check for an absolute path
240 if (path
[0] == DIR_SEPARATOR_CHAR
)
243 strcat(buf
, DIR_SEPARATOR_STRING
);
244 strcat(buf
, entry
->d_name
);
248 getcwd(buf
, sizeof(buf
));
249 strcat(buf
, DIR_SEPARATOR_STRING
);
251 strcat(buf
, entry
->d_name
);
254 if (stat(buf
, &stbuf
) == -1)
256 printf("Can't access '%s' (%s)\n", buf
, strerror(errno
));
260 if (S_ISDIR(stbuf
.st_mode
))
262 /* Skip subdirectories */
266 register_test(entry
->d_name
, type
);
273 printf("Can't open %s\n", path
);
279 dirp
= opendir(path
);
282 while ((entry
= readdir(dirp
)) != NULL
)
284 if (strcmp(entry
->d_name
, ".") == 0 || strcmp(entry
->d_name
, "..") == 0)
285 continue; // skip self and parent
287 // Check for an absolute path
288 if (path
[0] == DIR_SEPARATOR_CHAR
)
291 strcat(buf
, DIR_SEPARATOR_STRING
);
292 strcat(buf
, entry
->d_name
);
296 getcwd(buf
, sizeof(buf
));
297 strcat(buf
, DIR_SEPARATOR_STRING
);
299 strcat(buf
, entry
->d_name
);
302 if (stat(buf
, &stbuf
) == -1)
304 printf("Can't access '%s' (%s)\n", buf
, strerror(errno
));
308 if (S_ISDIR(stbuf
.st_mode
))
310 /* Skip subdirectories */
314 register_test(entry
->d_name
, type
);
320 printf("Can't open %s\n", path
);
330 is_file_changed(char *filename
, char *content
)
337 file
= fopen(filename
, "rb");
343 fseek(file
, 0, SEEK_END
);
345 fseek(file
, 0, SEEK_SET
);
351 filecontent
= malloc(size
);
352 if (filecontent
== NULL
)
358 n
= fread(filecontent
, 1, size
, file
);
360 if (n
!= strlen(content
))
367 if (strcmp(content
, filecontent
) != 0)
382 write_file_if_changed(char *filename
, char *content
)
387 if (is_file_changed(filename
, content
) == 0)
392 file
= fopen(filename
, "wb");
398 n
= fwrite(content
, 1, strlen(content
), file
);
405 static char KMSTUB
[] =
406 "/* This file is autogenerated. */\n"
408 "#include <roskrnl.h>\n"
409 "#include <../kmregtests/kmregtests.h>\n"
411 "typedef int (*TestRoutine)(int Command, char *Buffer);\n"
413 "extern void RegisterTests();\n"
415 "static PDEVICE_OBJECT KMRegTestsDeviceObject = NULL;\n"
416 "static PFILE_OBJECT KMRegTestsFileObject = NULL;\n"
418 "void AddTest(TestRoutine Routine)\n"
420 " UNICODE_STRING DriverName;\n"
421 " IO_STATUS_BLOCK IoStatus;\n"
422 " NTSTATUS Status;\n"
426 " if (KMRegTestsDeviceObject == NULL)\n"
428 " RtlInitUnicodeString(&DriverName, L\"\\\\Device\\\\KMRegTests\");\n"
429 " Status = IoGetDeviceObjectPointer(&DriverName, FILE_WRITE_ATTRIBUTES,\n"
430 " &KMRegTestsFileObject, &KMRegTestsDeviceObject);\n"
431 " if (!NT_SUCCESS(Status)) return;\n"
433 " KeInitializeEvent(&Event, NotificationEvent, FALSE);\n"
434 " Irp = IoBuildDeviceIoControlRequest(IOCTL_KMREGTESTS_REGISTER,\n"
435 " KMRegTestsDeviceObject, &Routine, sizeof(TestRoutine), NULL, 0, FALSE, &Event, &IoStatus);\n"
436 " Status = IoCallDriver(KMRegTestsDeviceObject, Irp);\n"
439 "void PrepareTests()\n"
441 " RegisterTests();\n"
444 static char UMSTUB
[] =
445 "/* This file is autogenerated. */\n"
447 "#include <windows.h>\n"
448 "#define NTOS_MODE_USER\n"
449 "#include <ntos.h>\n"
450 "#include \"regtests.h\"\n"
453 "AllocateMemory(ULONG Size)\n"
455 " return (PVOID) RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);\n"
459 "FreeMemory(PVOID Base)\n"
461 " RtlFreeHeap(RtlGetProcessHeap(), 0, Base);\n"
464 "/* This function will be called several times */\n"
465 "void PrepareTests()\n"
467 " static int testsRegistered = 0;\n"
468 " if (testsRegistered == 0)\n"
471 " hEvent = OpenEventW(\n"
472 " EVENT_ALL_ACCESS,\n"
474 " L\"WinRegTests\");\n"
475 " if (hEvent != NULL)\n"
477 " SetEvent(hEvent);\n"
478 " CloseHandle(hEvent);\n"
479 " testsRegistered = 1;\n"
480 " InitializeTests();\n"
481 " RegisterTests();\n"
482 " PerformTests(NULL, NULL);\n"
488 "REGTESTS path file makefile [-u umstubfile] [-k kmstubfile]\n"
490 " path Path to files\n"
491 " file Registration file to create\n"
492 " makefile Makefile to create\n"
493 " umstubfile Optional stub for running tests internal to a user-mode module\n"
494 " kmstubfile Optional stub for running tests internal to a kernel-mode module\n";
496 int main(int argc
, char **argv
)
508 strcpy(buf
, convert_path(argv
[1]));
509 if (buf
[strlen(buf
)] != DIR_SEPARATOR_CHAR
)
512 buf
[strlen(buf
)] = DIR_SEPARATOR_CHAR
;
518 printf("Missing path\n");
522 file
= convert_path(argv
[2]);
525 printf("Missing file\n");
529 makefile
= convert_path(argv
[3]);
530 if (makefile
[0] == 0)
532 printf("Missing makefile\n");
538 for (i
= 4; i
< argc
; i
++)
540 if (argv
[i
][0] == '-')
542 if (argv
[i
][1] == 'u')
544 umstubfile
= convert_path(argv
[++i
]);
545 if (umstubfile
[0] == 0)
547 printf("Missing umstubfile\n");
551 else if (argv
[i
][1] == 'k')
553 kmstubfile
= convert_path(argv
[++i
]);
554 if (kmstubfile
[0] == 0)
556 printf("Missing kmstubfile\n");
562 printf("Unknown switch\n");
569 /* Registration file */
570 out
= fopen(file
, "wb");
573 perror("Cannot create output file");
577 write_line("/* This file is autogenerated. */");
579 write_line("typedef int (*TestRoutine)(int Command, char *Buffer);");
585 write_line("extern void AddTest(TestRoutine Routine);");
587 write_line("void RegisterTests()");
598 out
= fopen(makefile
, "wb");
601 perror("Cannot create output makefile");
605 write_line("# This file is autogenerated.");
607 write_line("TESTS = \\");
615 /* User-mode stubfile */
616 if (umstubfile
!= NULL
)
618 if (write_file_if_changed(umstubfile
, UMSTUB
) != 0)
620 perror("Cannot create output user-mode stubfile");
625 /* Kernel-mode stubfile */
626 if (kmstubfile
!= NULL
)
628 if (write_file_if_changed(kmstubfile
, KMSTUB
) != 0)
630 perror("Cannot create output kernel-mode stubfile");