source: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 4.3 KB
Line 
1/*
2 * apilist.c
3 */
4
5#include <ctype.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "mrdb.h"
10#include "mrdberror.h"
11#include "apilist.h"
12#include <mruby/compile.h>
13#include <mruby/irep.h>
14#include <mruby/debug.h>
15
16#define LINE_BUF_SIZE MAX_COMMAND_LINE
17
18typedef struct source_file {
19 char *path;
20 uint16_t lineno;
21 FILE *fp;
22} source_file;
23
24static void
25source_file_free(mrb_state *mrb, source_file *file)
26{
27 if (file != NULL) {
28 if (file->path != NULL) {
29 mrb_free(mrb, file->path);
30 }
31 if (file->fp != NULL) {
32 fclose(file->fp);
33 file->fp = NULL;
34 }
35 mrb_free(mrb, file);
36 }
37}
38
39static char*
40build_path(mrb_state *mrb, const char *dir, const char *base)
41{
42 int len;
43 char *path = NULL;
44
45 len = strlen(base) + 1;
46
47 if (strcmp(dir, ".")) {
48 len += strlen(dir) + sizeof("/") - 1;
49 }
50
51 path = mrb_malloc(mrb, len);
52 memset(path, 0, len);
53
54 if (strcmp(dir, ".")) {
55 strcat(path, dir);
56 strcat(path, "/");
57 }
58 strcat(path, base);
59
60 return path;
61}
62
63static char*
64dirname(mrb_state *mrb, const char *path)
65{
66 size_t len;
67 char *p, *dir;
68
69 if (path == NULL) {
70 return NULL;
71 }
72
73 p = strrchr(path, '/');
74 len = p != NULL ? (size_t)(p - path) : strlen(path);
75
76 dir = mrb_malloc(mrb, len + 1);
77 strncpy(dir, path, len);
78 dir[len] = '\0';
79
80 return dir;
81}
82
83static source_file*
84source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename)
85{
86 source_file *file = NULL;
87
88 file = mrb_malloc(mrb, sizeof(source_file));
89
90 memset(file, '\0', sizeof(source_file));
91 file->fp = fopen(filename, "rb");
92
93 if (file->fp == NULL) {
94 source_file_free(mrb, file);
95 return NULL;
96 }
97
98 file->lineno = 1;
99 file->path = mrb_malloc(mrb, strlen(filename) + 1);
100 strcpy(file->path, filename);
101 return file;
102}
103
104static mrb_bool
105remove_newlines(char *s, FILE *fp)
106{
107 int c;
108 char *p;
109 size_t len;
110
111 if ((len = strlen(s)) == 0) {
112 return FALSE;
113 }
114
115 p = s + len - 1;
116
117 if (*p != '\r' && *p != '\n') {
118 return FALSE;
119 }
120
121 if (*p == '\r') {
122 /* peek the next character and skip '\n' */
123 if ((c = fgetc(fp)) != '\n') {
124 ungetc(c, fp);
125 }
126 }
127
128 /* remove trailing newline characters */
129 while (s <= p && (*p == '\r' || *p == '\n')) {
130 *p-- = '\0';
131 }
132
133 return TRUE;
134}
135
136static void
137show_lines(source_file *file, uint16_t line_min, uint16_t line_max)
138{
139 char buf[LINE_BUF_SIZE];
140 int show_lineno = 1, found_newline = 0, is_printed = 0;
141
142 if (file->fp == NULL) {
143 return;
144 }
145
146 while (fgets(buf, sizeof(buf), file->fp) != NULL) {
147 found_newline = remove_newlines(buf, file->fp);
148
149 if (line_min <= file->lineno) {
150 if (show_lineno) {
151 printf("%-8d", file->lineno);
152 }
153 show_lineno = found_newline;
154 printf(found_newline ? "%s\n" : "%s", buf);
155 is_printed = 1;
156 }
157
158 if (found_newline) {
159 if (line_max < ++file->lineno) {
160 break;
161 }
162 }
163 }
164
165 if (is_printed && !found_newline) {
166 printf("\n");
167 }
168}
169
170char*
171mrb_debug_get_source(mrb_state *mrb, mrdb_state *mrdb, const char *srcpath, const char *filename)
172{
173 int i;
174 FILE *fp;
175 const char *search_path[3];
176 char *path = NULL;
177
178 search_path[0] = srcpath;
179 search_path[1] = dirname(mrb, mrb_debug_get_filename(mrdb->dbg->root_irep, 0));
180 search_path[2] = ".";
181
182 for (i = 0; i < 3; i++) {
183 if (search_path[i] == NULL) {
184 continue;
185 }
186
187 if ((path = build_path(mrb, search_path[i], filename)) == NULL) {
188 continue;
189 }
190
191 if ((fp = fopen(path, "rb")) == NULL) {
192 mrb_free(mrb, path);
193 path = NULL;
194 continue;
195 }
196 fclose(fp);
197 break;
198 }
199
200 mrb_free(mrb, (void *)search_path[1]);
201
202 return path;
203}
204
205int32_t
206mrb_debug_list(mrb_state *mrb, mrb_debug_context *dbg, char *filename, uint16_t line_min, uint16_t line_max)
207{
208 char *ext;
209 source_file *file;
210
211 if (mrb == NULL || dbg == NULL || filename == NULL) {
212 return MRB_DEBUG_INVALID_ARGUMENT;
213 }
214
215 ext = strrchr(filename, '.');
216
217 if (ext == NULL || strcmp(ext, ".rb")) {
218 printf("List command only supports .rb file.\n");
219 return MRB_DEBUG_INVALID_ARGUMENT;
220 }
221
222 if (line_min > line_max) {
223 return MRB_DEBUG_INVALID_ARGUMENT;
224 }
225
226 if ((file = source_file_new(mrb, dbg, filename)) != NULL) {
227 show_lines(file, line_min, line_max);
228 source_file_free(mrb, file);
229 return MRB_DEBUG_OK;
230 }
231 else {
232 printf("Invalid source file named %s.\n", filename);
233 return MRB_DEBUG_INVALID_ARGUMENT;
234 }
235}
Note: See TracBrowser for help on using the repository browser.